package com.example.demo.controller;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.example.demo.dto.DlTpExclex;
import com.example.demo.dto.DynamicExcelData;
import com.example.demo.service.IndexOrNameDataListener;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * @ClassName: Dc
 * @Description: TODO
 * @Author zhangguangyan
 * @Date 2023/09/08/ 17:24:17
 * @Version 1.0
 */
@RestController
@RequestMapping("/export")
@Slf4j
public class ExportController {

    @CrossOrigin
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {

        //模拟数据
        //一般动态数据使用的是List，然后内部使用Map进行数据的接受
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            HashMap<String, Object> map = new HashMap<>();
            for (int j = 0; j < 5; j++) {
                map.put("title"+j,i+","+j);
            }
            //这个用于测试值如果为null时，能否进行默认值填充
            map.put("title5",null);
            list.add(map);
        }


        //使用LinkedHashMap进行表头字段映射
        LinkedHashMap<String, DynamicExcelData> nameMap = new LinkedHashMap<>();
        nameMap.put("title1",new DynamicExcelData("年龄","0"));
        nameMap.put("title0",new DynamicExcelData("姓名","0"));
        nameMap.put("title2",new DynamicExcelData("职业","0"));
        nameMap.put("title3",new DynamicExcelData("爱好","0"));
        nameMap.put("title4", new DynamicExcelData("小名", "0"));
        nameMap.put("title5", new DynamicExcelData("空白字段", "0"));

        //调用方法,方法已在步骤3进行介绍
        dynamicExport(response,nameMap, list,"模板");

    }

    @CrossOrigin
    @PostMapping(value = {"/uploada"})
    public Map<String, Object> fileUploada(
                                          @RequestPart(value = "excelFile") MultipartFile multipartFile) throws IOException {
        log.info("fileName: " + multipartFile.getOriginalFilename());
        Map<String, Object> respMap = new HashMap<>();
            /*
             * 将文件转化为输入流资源
             * 为了避免生成临时文件，这里使用了 ByteArrayResource，且这里需要重写其中的 getFilename() 方法
             * */
            ByteArrayResource byteArrayResourceOfFile = new ByteArrayResource(multipartFile.getBytes()) {
                @Override
                public String getFilename() {
                    return multipartFile.getOriginalFilename();
                }
            };
            // 创建 MultiValueMap 实例，这里使用 LinkedMultiValueMap 这一实现类来进行实例化
            MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>(10);
            multiValueMap.add("file", byteArrayResourceOfFile);

            return respMap;
    }
@CrossOrigin
    @PostMapping(value = {"/upload"})
    public Map<String, Object> fileUpload(@RequestPart(value = "excelFile") MultipartFile multipartFile) throws IOException {
        log.info("fileName: " + multipartFile.getOriginalFilename());
        Map<String, Object> respMap = new HashMap<>();
    EasyExcel.read(multipartFile.getInputStream(), DlTpExclex.class, new IndexOrNameDataListener()).sheet().headRowNumber(2).doRead();
//    EasyExcel.read(multipartFile.getInputStream(), DlTpExclex.class, new ReadListener<DlTpExclex>() {
//        /**
//         * 单次缓存的数据量
//         */
//        public static final int BATCH_COUNT = 1000;
//        /**
//         *临时存储
//         */
//        private List<DlTpExclex> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
//
//        @Override
//        public void invoke(DlTpExclex data, AnalysisContext context) {
//            cachedDataList.add(data);
//            if (cachedDataList.size() >= BATCH_COUNT) {
//                saveData();
//                // 存储完成清理 list
//                cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
//            }
//        }
//
//        @Override
//        public void doAfterAllAnalysed(AnalysisContext context) {
//            saveData();
//        }
//
//        /**
//         * 加上存储数据库
//         */
//        private void saveData() {
//            log.info("{}条数据，开始存储数据库！", cachedDataList.size());
//            log.info("存储数据库成功！");
//        }
//    }).sheet().doRead();
            return respMap;
    }


    /**
     * 列表
     */
    public static void dynamicExport(HttpServletResponse response,
                                     LinkedHashMap<String,DynamicExcelData> nameMap,
                                     List<Map<String, Object>> list,
                                     String sheetName) throws IOException {
        if(CollUtil.isEmpty(list)){
            return;
        }
        if(nameMap==null){
            throw new RuntimeException("请填写好映射表数据");
        }

        int size = list.size();
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            dataList.add(new ArrayList<>());
        }

        //获取表头
        ArrayList<List<String>> head = new ArrayList<>();
        for (Map.Entry<String, DynamicExcelData> titleMap : nameMap.entrySet()) {
            DynamicExcelData data = titleMap.getValue();
            head.add(Collections.singletonList(data.getName()));
        }

        //数据重组
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = list.get(i);
            List<String> columns = dataList.get(i);
            for (Map.Entry<String, DynamicExcelData> sortNameEntry : nameMap.entrySet()) {
                String key = sortNameEntry.getKey();
                Object value = map.get(key);
                columns.add(value!=null?String.valueOf(value):sortNameEntry.getValue().getDefaultValue());
            }
        }

        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        EasyExcel.write(response.getOutputStream()).head(head)
                .sheet(sheetName).doWrite(dataList);
    }

}

